// INCLUDES --------------------------------------------------------------------------
#include "Framework.h"

// FUNCTIONS -------------------------------------------------------------------------

// --------------- TEMP -----------------
void renderSomething()
{
  static float r = 0;
  glPushMatrix();
    glTranslatef(0.0f, 0.0f, -10.0f);
    glRotatef(r, 0, 1, 0);
    glutSolidTeapot(1.0f);
  glPopMatrix();
  r += 0.1f;
}
// --------------------------------------

/* the framework clock runs globally with X fps. it gets updated every
   given (1/X)*1000 mSec's and calls WindowRedisplay() accordingly.
   
   Example:
   FPS=60 -> Update Interval: (1/60)*1000 ~= 16,6 mSec's
   FPS=30 -> Update Interval: (1/30)*1000 ~= 33,3 mSec's
   
   TODO: account for wrap-around of clock!!!
*/
#define UPDATE_FPS            60.0f                            // update framerate
#define FRAMEWORK_GRANULARITY (fp64)(1.0/UPDATE_FPS * 1000.0f) // update interval in mSec's

static fp64 frameworkClock = 0.0f;                             // the global engine clock
static bool granularityIncrease = false;                       // flag marks an "granularity increase"

// update engine's clock granularity
void UpdateFrameworkClock()
{
#ifdef USE_FRAMEWORK_GRANULARITY_FOR_UPDATE

  static ui64 now = 0,       // the current time
              timestamp = 0; // timestamp of the next clock update
  static fp64 factor = 1.0f; // factor of passed time in relation to FRAMEWORK_GRANULARITY

  now = TimeMs();       // get current time

  if (now >= timestamp) // check if it's time to increase the granularity...
  {
    /* calculate the factor of the total passed time:

       clock update time -> at least this many mSec's passed since the last update
       now - timestamp   -> additional passed time (due to lags, etc)
    */
    factor = (FRAMEWORK_GRANULARITY + (fp64)(now - timestamp)) / FRAMEWORK_GRANULARITY;

    frameworkClock += FRAMEWORK_GRANULARITY * factor; // add up passed time
    timestamp = now + (ui64)FRAMEWORK_GRANULARITY;    // re-calculate next increase-timestamp

    granularityIncrease = true;  // mark increase
  }
  else // granularity hasn't increased...
  {
    granularityIncrease = false; // mark NO increase
  }

#else

  // just add up passed time
  frameworkClock += FRAMEWORK_GRANULARITY;
  // just mark granularity as increased by DEFAULT
  granularityIncrease = true;

#endif // USE_FRAMEWORK_GRANULARITY_FOR_UPDATE
};

// retrieve main engine clock (-> updated every X fps)
fp64 GetFrameworkClock() { return frameworkClock; };

// main engine init
void Init()
{
  // initialize rasterization pipeline
  RenderInit();
};

// main engine computation
void Compute()
{
  // update the internal engine clock
  UpdateFrameworkClock();

  // if clock granularity has increased -> invalidate window contents
  if (granularityIncrease == true) WindowRedisplay();
};

// main engine render
void Render()
{
  // update framerate
  RenderCalculateFPS();

  // setup camera parameters
  RenderSetCamera();

  // clear screen
  RenderClear();

    // TODO: SCENE RENDERING NEEDS TO BE INSERTED HERE
    renderSomething();

  // flush pipeline
  RenderFlush();

  // swap buffers
  WindowSwapBuffers();
};
